/******************************************************************************************************************
版权所有：郑州新开普电子股份有限公司
文件名称：Blacklist.c
文件概述：主要是黑名单操作的处理,包括黑名单存储\比较；
作    者：秦天福
编写日期：2009年12月17日
版 本 号：V1.00
变更记录：
******************************************************************************************************************/

#include "../includes.h"
#include "AH_Blacklist.h"
#include "AH_BlkDirFileLib.h"           //黑名单目录文件
#include "APP_Blacklist.h"

/*
**************************************************************************************************************
*										  常 量
**************************************************************************************************************
*/
#define DEF_NC_BlkFileNum			( DEF_NC_BlkFileMaxNum  )				//定义黑名单文件数量

#define	BLACKLISTFILE_LENGTH		( 40ul )								//黑名单指针文件长度,不能改变

/*
**************************************************************************************************************
*										  类 型
**************************************************************************************************************
*/

/*
**************************************************************************************************************
*										  变 量
**************************************************************************************************************
*/
static _STRUCT_BLACKLISTFILE	BlacklistFile[DEF_NC_BlkFileNum];
//定义黑名单文件排序及比对使用的临时缓冲区,//该缓冲区的大小等于5个黑名单文件中最大的黑
//名单文件块的大小,最小不能小于4块Flash空间的大小,这里只是临时定义,请用户根据实际定义

/*
**************************************************************************************************************
*         								  函 数
**************************************************************************************************************
*/
extern void NC_FileLock( void );
extern void NC_FileUnLock( void );

/***************************************************************************************************************
函数功能：加载黑名单区基本信息,主要是将配置文件中的内容加载到内存中
函数原型：APP_ReadBlacklistFlashInfo( U32 ID ,_STRUCT_BLACKBASICINFO *pBlacklistBasic )
输入参数：U32 ID:									黑名单文件编号,编号为1-5
		  _STRUCT_BLACKBASICINFO *pBlacklistBasic	黑名单基本信息结构体指针
输出参数：返回指定黑名单文件的基本信息
返    回：0   		成功
		  !0		失败
***************************************************************************************************************/
U32	APP_ReadBlacklistFlashInfo( U32 ID ,_STRUCT_BLACKBASICINFO *pBlacklistBasic )
{
	switch( ID )
	{
		case 1:
			pBlacklistBasic->Id = ID;									//黑名单区ID
			pBlacklistBasic->StartAddress = 0;							//黑名单区开始地址
			pBlacklistBasic->FlashSize = FLASH_PAGE_SIZE;				//Flash每块字节数
			pBlacklistBasic->FlashNumber = BLACKLIST1_PAGE_SIZE;		//每块黑名单中包含Flash块的数量
			pBlacklistBasic->BlockNumber = BLACKLIST1_SECTION_SIZE;		//每个黑名单区中包含黑名单块的数量，必须是偶数块，并且大于等于6
			pBlacklistBasic->BlackLength = BLACKLIST1_LENGTH;			//黑名单长度
			pBlacklistBasic->CompareLength = BLACKLIST1_COMPARE_LENGTH;	//比较黑名单长度
			pBlacklistBasic->FlushType = BLACKLIST1_FLUSH_METHOD;		//黑名单对齐方式，0：左对齐，1：右对齐
			break;
		case 2:
			pBlacklistBasic->Id = ID;									//黑名单区ID
			pBlacklistBasic->StartAddress = 0;							//黑名单区开始地址
			pBlacklistBasic->FlashSize = FLASH_PAGE_SIZE;				//Flash每块字节数
			pBlacklistBasic->FlashNumber = BLACKLIST2_PAGE_SIZE;		//每块黑名单中包含Flash块的数量
			pBlacklistBasic->BlockNumber = BLACKLIST2_SECTION_SIZE;		//每个黑名单区中包含黑名单块的数量，必须是偶数块，并且大于等于6
			pBlacklistBasic->BlackLength = BLACKLIST2_LENGTH;			//黑名单长度
			pBlacklistBasic->CompareLength = BLACKLIST2_COMPARE_LENGTH;	//比较黑名单长度
			pBlacklistBasic->FlushType = BLACKLIST2_FLUSH_METHOD;		//黑名单对齐方式，0：左对齐，1：右对齐
			break;
		case 3:
			pBlacklistBasic->Id = ID;									//黑名单区ID
			pBlacklistBasic->StartAddress = 0;							//黑名单区开始地址
			pBlacklistBasic->FlashSize = FLASH_PAGE_SIZE;				//Flash每块字节数
			pBlacklistBasic->FlashNumber = BLACKLIST3_PAGE_SIZE;		//每块黑名单中包含Flash块的数量
			pBlacklistBasic->BlockNumber = BLACKLIST3_SECTION_SIZE;		//每个黑名单区中包含黑名单块的数量，必须是偶数块，并且大于等于6
			pBlacklistBasic->BlackLength = BLACKLIST3_LENGTH;			//黑名单长度
			pBlacklistBasic->CompareLength = BLACKLIST3_COMPARE_LENGTH;	//比较黑名单长度
			pBlacklistBasic->FlushType = BLACKLIST3_FLUSH_METHOD;		//黑名单对齐方式，0：左对齐，1：右对齐
			break;
		case 4:
			pBlacklistBasic->Id = ID;									//黑名单区ID
			pBlacklistBasic->StartAddress = 0;							//黑名单区开始地址
			pBlacklistBasic->FlashSize = FLASH_PAGE_SIZE;				//Flash每块字节数
			pBlacklistBasic->FlashNumber = BLACKLIST4_PAGE_SIZE;		//每块黑名单中包含Flash块的数量
			pBlacklistBasic->BlockNumber = BLACKLIST4_SECTION_SIZE;		//每个黑名单区中包含黑名单块的数量，必须是偶数块，并且大于等于6
			pBlacklistBasic->BlackLength = BLACKLIST4_LENGTH;			//黑名单长度
			pBlacklistBasic->CompareLength = BLACKLIST4_COMPARE_LENGTH;	//比较黑名单长度
			pBlacklistBasic->FlushType = BLACKLIST4_FLUSH_METHOD;		//黑名单对齐方式，0：左对齐，1：右对齐
			break;
		case 5:
			pBlacklistBasic->Id = ID;									//黑名单区ID
			pBlacklistBasic->StartAddress = 0;							//黑名单区开始地址
			pBlacklistBasic->FlashSize = FLASH_PAGE_SIZE;				//Flash每块字节数
			pBlacklistBasic->FlashNumber = BLACKLIST5_PAGE_SIZE;		//每块黑名单中包含Flash块的数量
			pBlacklistBasic->BlockNumber = BLACKLIST5_SECTION_SIZE;		//每个黑名单区中包含黑名单块的数量，必须是偶数块，并且大于等于6
			pBlacklistBasic->BlackLength = BLACKLIST5_LENGTH;			//黑名单长度
			pBlacklistBasic->CompareLength = BLACKLIST5_COMPARE_LENGTH;	//比较黑名单长度
			pBlacklistBasic->FlushType = BLACKLIST5_FLUSH_METHOD;		//黑名单对齐方式，0：左对齐，1：右对齐
			break;
		default:
			return 1;
	}
	return 0;
}

/***************************************************************************************************************
函数功能：创建黑名单文件,黑名单文件只有创建之后才能使用
函数原型：APP_CreateBlacklistFile( U32 ID )
输入参数：U32 ID:		黑名单文件编号,编号为1-5, 
输出参数：
返    回：NCAP_TRUE   		创建成功
          0x0000FFFF        flash硬件故障 
		  !NCAP_TRUE		创建失败
***************************************************************************************************************/
U32 APP_CreateBlacklistFile( U32 ID )
{
	U32 i,id;

	if( ( ID > DEF_NC_BlkFileNum ) || ( ID == 0 ) )
	{ return 200; }

	NC_FileLock();

	id = ( ID - 1 );
	
	BlacklistFile[id].OpenStat = 1;			//黑名单文件打开状态 1打开,
	BlacklistFile[id].MiddleBlockNum = 0;	//中间排序过的块数
	BlacklistFile[id].Rvs16 = 0xFFFF;		//保留2字节,主要是对齐使用
	BlacklistFile[id].BlackVer = 0;			//黑名单版本
	BlacklistFile[id].AllStaBlock = 0;		//全量开始块
	BlacklistFile[id].AllStaBlock = 0;		//全量开始块
	BlacklistFile[id].AllEndBlock = 0;		//全量结束块
	BlacklistFile[id].AddBlackNum = 0;		//增量黑名单个数
	BlacklistFile[id].AddCurBlock = 3;		//增量当前块
	BlacklistFile[id].AddState = 0xFF;		//黑名单状态
	for( i = 0; i < 14; i++ )				//保留字节
	{ BlacklistFile[id].Rvs[i] = 0xFF; }

	i = AH_Create_BlkDirFile( ID );
	if( i != 0 )
	{
		NC_FileUnLock();
		return i;
    }
	
	i = AH_Write_BlkDirFile( ID, (U08 *)(&BlacklistFile[id]) );	

	NC_FileUnLock();
	return	i;
}

/***************************************************************************************************************
函数功能：打开黑名单文件,主要是打开黑名单文件,程序运行之后需要创建文件,获取运行需要的信息
函数原型：APP_OpenBlacklistFile( U32 ID )
输入参数：U32 ID:		黑名单文件编号,编号为1-5
输出参数：
返    回：NCAP_TRUE   		成功
		  0x0000FFFF        FLASH硬件故障
		  !NCAP_TRUE	    失败
***************************************************************************************************************/
U32 APP_OpenBlacklistFile( U32 ID )
{
	U32 Rcode,id;

	if( ( ID > DEF_NC_BlkFileNum ) || ( ID == 0 ) )
	{ return 200; }

	NC_FileLock();

	id = ( ID - 1 );

	Rcode = AH_Open_BlkDirFile( ID );
	if( Rcode != 0 )
	{ goto RET;	}
	
	Rcode = AH_Read_BlkDirFile( ID, (U08 *)(&BlacklistFile[id]) );
	if( Rcode != 0 )
	{ goto RET;	}

	if( BlacklistFile[id].OpenStat != 1 )
	{
		Rcode = 400;
		goto RET; 
	}

	RET:
	NC_FileUnLock();
	return	Rcode;
}

/***************************************************************************************************************
函数功能：更新黑名单版本,主要是变更黑名单的版本号
函数原型：APP_UpdateBlacklistVersion( U32 ID, U32 BlacklistVersion )
输入参数：U32 ID:		黑名单文件编号,编号为1-5
输出参数：
返    回：NCAP_TRUE   		成功
		  0x0000FFFF        FLASH硬件故障
		  !NCAP_TRUE	    失败
***************************************************************************************************************/
U32 APP_UpdateBlacklistVersion( U32 ID, U32 BlacklistVersion )
{
	U32 Rcode,id;

	if( ( ID > DEF_NC_BlkFileNum ) || ( ID == 0 ) )
	{ return 200; }

	NC_FileLock();

	id = ( ID - 1 );
		
	BlacklistFile[id].BlackVer = BlacklistVersion;
	Rcode = AH_Write_BlkDirFile( ID, (U08 *)(&BlacklistFile[id]) );

	NC_FileUnLock();
	return	Rcode;
}

/***************************************************************************************************************
函数功能：读黑名单版本
函数原型：APP_ReadBlacklistVersion( U32 ID, U32 *BlacklistVersion )
输入参数：U32 ID:					黑名单文件编号,编号为1-5
		  U32 *BlacklistVersion		黑名单版本指针
输出参数：返回黑名单版本
返    回：NCAP_TRUE   		成功
		  0x0000FFFF        FLASH硬件故障
		  !NCAP_TRUE	    失败
***************************************************************************************************************/
U32 APP_ReadBlacklistVersion( U32 ID, U32 *BlacklistVersion )
{
	U32 Rcode,id;

	if( ( ID > DEF_NC_BlkFileNum ) || ( ID == 0 ) )
	{ return 200; }

	NC_FileLock();

	id = ( ID - 1 );

	Rcode = AH_MemorDataCrc( (U08 *)(&BlacklistFile[id]), ( BLACKLISTFILE_LENGTH - 2 ), 2 );
	if( Rcode != 0 )
	{
		Rcode = APP_OpenBlacklistFile( ID );
		if( Rcode != 0 )
		{
			NC_FileUnLock();
			return Rcode;
	    }
	}

	//如果文件没有创建,也是返回失败的
	if( BlacklistFile[id].OpenStat != 1 )
	{
		NC_FileUnLock();
		return 400;									//黑名单文件打开失败
	}

	*BlacklistVersion = BlacklistFile[id].BlackVer;

	NC_FileUnLock();
	return	0;
}


/***************************************************************************************************************
函数功能：读指定黑名单文件的黑名单数量
函数原型：APP_ReadBlacklistVersion( U32 ID, U32 *BlacklistVersion )
输入参数：U32 ID:					黑名单文件编号,编号为1-5
		  U32 *BlacklistVersion		黑名单版本指针
输出参数：返回黑名单版本
返    回：NCAP_TRUE   		成功
		  0x0000FFFF        FLASH硬件故障
		  !NCAP_TRUE	    失败
***************************************************************************************************************/
U32 APP_ReadBlacklistNumber( U32 ID, U32 *BlacklistNumber )
{
	U32 Rcode,id;
	_STRUCT_BLACKBASICINFO BlacklistBasic;

	if( ( ID > DEF_NC_BlkFileNum ) || ( ID == 0 ) )
	{ return 200; }

	NC_FileLock();

	id = ( ID - 1 );

	Rcode = APP_ReadBlacklistFlashInfo( ID, &BlacklistBasic );
    if( Rcode != 0 )
	{ goto RET; }

	Rcode = AH_MemorDataCrc((U08 *)(&BlacklistFile[id]), BLACKLISTFILE_LENGTH - 2, 2 );
	if( Rcode != 0 )
	{
		Rcode = APP_OpenBlacklistFile( ID );
		if( Rcode != 0 )
		{ goto RET; }
	}

	//如果文件没有创建,也是返回失败的
	if( BlacklistFile[id].OpenStat != 1 )
	{
		NC_FileUnLock();
		return 400;												//黑名单文件打开失败
	}
	
	//首先计算全量黑名单的块数
	Rcode = ( ( ( BlacklistFile[id].AllEndBlock + BlacklistBasic.BlockNumber ) - BlacklistFile[id].AllStaBlock ) % BlacklistBasic.BlockNumber );
	//再加上中间排序黑名单的块数
	Rcode += BlacklistFile[id].MiddleBlockNum;
	//计算全量和中间排序过的黑名单的总个数
	Rcode =  ( Rcode * ( ( BlacklistBasic.FlashNumber * BlacklistBasic.FlashSize ) / BlacklistBasic.BlackLength ) );
	//再加上增量黑名单个数
	*BlacklistNumber = ( Rcode + BlacklistFile[id].AddBlackNum );

	Rcode = 0;

	RET:
	NC_FileUnLock();
	return	Rcode;
}

/***************************************************************************************************************
函数功能：更新黑名单文件保留字节内容,长度为14字节
函数原型：U32 APP_UpdateBlacklistVersion( U32 ID, U08 *pBlacklistReserveBuf )
输入参数：U32 ID:						黑名单文件编号	1-5
		  U08 *pBlacklistReserveBuf:	要写入的内容的首指针,长度固定为14字节
输出参数：
返    回：NCAP_TRUE   		成功
		  0x0000FFFF        FLASH硬件故障
		  !NCAP_TRUE	    失败
***************************************************************************************************************/
U32 APP_UpdateBlacklistReserve( U32 ID, U08 *pBlacklistReserveBuf )
{
	U32 i,id;

	if( ( ID > DEF_NC_BlkFileNum ) || ( ID == 0 ) )
	{ return 200; }

	NC_FileLock();

	id = ( ID - 1 );
	
	for( i = 0; i < 14; i++ )									//保留字节
	{ BlacklistFile[id].Rvs[i] = pBlacklistReserveBuf[i]; }

	i = AH_Write_BlkDirFile( ID, (U08 *)(&BlacklistFile[id]) );

	NC_FileUnLock();

	return	i;
}

/***************************************************************************************************************
函数功能：读黑名单文件保留字节,长度为14字节
函数原型：U32 APP_ReadBlacklistVersion( U32 ID, U08 *pBlacklistReserveBuf )
输入参数：U32 ID:						黑名单文件编号,编号为1-5
		  U08 *pBlacklistReserveBuf:	要读出的内容的首指针,长度固定为14字节
输出参数：返回黑名单保留字节中的内容
返    回：NCAP_TRUE   		创建成功
		  0x0000FFFF        FLASH硬件故障
		  !NCAP_TRUE	    创建失败
***************************************************************************************************************/
U32 APP_ReadBlacklistReserve( U32 ID, U08 *pBlacklistReserveBuf )
{
	U32 i;
	U32 Rcode,id;

	if( ( ID > DEF_NC_BlkFileNum ) || ( ID == 0 ) )
	{ return 200; }

	NC_FileLock();

	id = ( ID - 1 );

	Rcode = AH_MemorDataCrc( (U08 *)(&BlacklistFile[id]), ( BLACKLISTFILE_LENGTH - 2 ), 2 );
	if( Rcode != 0 )
	{
		Rcode = APP_OpenBlacklistFile( ID );
		if( Rcode != 0 )
		{
			NC_FileUnLock();
			return Rcode;
	    }
	}

	//如果文件没有创建,也是返回失败的
	if( BlacklistFile[id].OpenStat != 1 )
	{
		NC_FileUnLock();
		return 400;												//黑名单文件打开失败
	}

	for( i = 0; i < 14; i++ )									//保留字节
	{ pBlacklistReserveBuf[i] = BlacklistFile[id].Rvs[i]; }
	
	NC_FileUnLock();
	return 0;
}


/***************************************************************************************************************
函数功能：向指定黑名单文件中写入黑名单
函数原型：U32	APP_SaveBlacklist( U32 ID, U08 *pBlacklist, U32 Blacknumber )
输入参数：U32 ID:									黑名单文件编号,编号为1-5
          U08 *pBlacklist:							要写入黑名单的首指针
          U32 Blacknumber:							要写入黑名单的数量
          U08 *pTemp:								用于合并黑名单区的数据,大小等于一个黑名单块的大小(pBlackBasicInfo->FlashSize * pBlackBasicInfo->FlashNumber)
输出参数：黑名单指针信息会发生变更,请及时保存相关信息
返    回：NCAP_TRUE   		成功
		  0x0000FFFF        FLASH硬件故障
		  !NCAP_TRUE	    失败
***************************************************************************************************************/
U32	APP_SaveBlacklist( U32 ID, U08 *pBlacklist, U08 BlackNumber, U08 *pTemp )
{
	_STRUCT_BLACKBASICINFO BlacklistInfo;		        //定义黑名单基本信息
	U32 Rcode,id;								    	//定义函数返回值

	if( ( ID > DEF_NC_BlkFileNum ) || ( ID == 0 ) )
	{ return 200; }

	NC_FileLock();

	id = ( ID - 1 );
	
	//首先读函数基本信息,这是处理黑名单所必须的;
	Rcode = APP_ReadBlacklistFlashInfo( ID, &BlacklistInfo );
	if( Rcode != 0 )
	{ goto RET;	}

	//在判读黑名单指针是否过校验,如果不过校验则需要从FRAM中重新读取
	Rcode = AH_MemorDataCrc((U08 *)(&BlacklistFile[id]), BLACKLISTFILE_LENGTH-2, 2 );
	if( Rcode != 0 )
	{
		Rcode = APP_OpenBlacklistFile( ID );
		if( Rcode != 0 )
		{ goto RET;	}
	}

	//如果文件没有创建,也是返回失败的
	if( BlacklistFile[id].OpenStat != 1 )
	{
		Rcode = 400;
		goto RET; 
	}

	//如果增量黑名单的数量超过了每个黑名单块最大的数量,就需要进行排序(增量黑名单数量>=((Flash块大小*每个黑名单块的Flash块数)/黑名单长度))
	if( BlacklistFile[id].AddBlackNum >= ( ( BlacklistInfo.FlashSize * BlacklistInfo.FlashNumber ) / BlacklistInfo.BlackLength ) )
	{
		//需要进行排序,存入中间排序黑名单区
		Rcode = AH_SaveMiddleBlack( &BlacklistInfo , &BlacklistFile[id], pTemp );//保存中间排序黑名单如果不成功则返回错误
        if( Rcode != 0 )
		{ goto RET;	}

		//更新FRAM存储器中的黑名单指针
		Rcode = AH_Write_BlkDirFile( ID, (U08 *)(&BlacklistFile[id]) );//保存中间排序黑名单如果不成功则返回错误
		if( Rcode != 0 )
		{ goto RET;	}

		//如果中间排序块大于等于2块，需要将中间层合并到全量黑名单区
		if( BlacklistFile[id].MiddleBlockNum >= 2 )
		{
			Rcode = AH_SaveAllBlack( &BlacklistInfo , &BlacklistFile[id], pTemp );//保存全量黑名单如果不成功则返回错误
			if( Rcode != 0 )
		    { goto RET;	}

			//更新FRAM存储器中的黑名单指针
			Rcode = AH_Write_BlkDirFile( ID, (U08 *)(&BlacklistFile[id]) );
			if( Rcode != 0 )
			{ goto RET;	}
		}
	}

	//保存黑名单
	Rcode = AH_SaveAddBlack( &BlacklistInfo, &BlacklistFile[id], pBlacklist, BlackNumber , pTemp);
	if( Rcode != 0 )
	{ goto RET;	}

	//更新FRAM存储器中的黑名单指针
	Rcode = AH_Write_BlkDirFile( ID, (U08 *)(&BlacklistFile[id]) );
	if( Rcode != 0 )
	{ goto RET;	}

	//如果增量黑名单的数量超过了每个黑名单块最大的数量,就需要进行排序(增量黑名单数量>=((Flash块大小*每个黑名单块的Flash块数)/黑名单长度))
	if( BlacklistFile[id].AddBlackNum >= ( ( BlacklistInfo.FlashSize * BlacklistInfo.FlashNumber ) / BlacklistInfo.BlackLength ) )
	{
		//需要进行排序,存入中间排序黑名单区
		Rcode = AH_SaveMiddleBlack( &BlacklistInfo , &BlacklistFile[id], pTemp );//保存中间排序黑名单如果不成功则返回错误
		if( Rcode != 0 )
	    { goto RET;	}

		//更新FRAM存储器中的黑名单指针
		Rcode = AH_Write_BlkDirFile( ID, (U08 *)(&BlacklistFile[id]) );
		if( Rcode != 0 )
	    { goto RET;	}

		//如果中间排序块大于等于2块，需要将中间层合并到全量黑名单区
		if( BlacklistFile[id].MiddleBlockNum >= 2 )
		{
			Rcode = AH_SaveAllBlack( &BlacklistInfo , &BlacklistFile[id], pTemp );
			if( Rcode != 0 )
	        { goto RET;	}

			//更新FRAM存储器中的黑名单指针
			Rcode = AH_Write_BlkDirFile( ID, (U08 *)(&BlacklistFile[id]) );
			if( Rcode != 0 )
	        { goto RET;	}
		}
	}

	RET:
	NC_FileUnLock();
	return Rcode;
}

/***************************************************************************************************************
函数功能：在指定黑名单文件中查找黑名单
函数原型：U32 APP_FindBlacklist( U32 ID, U08 *pBlacklist, U08 *pBlacklistState, U08 *pTemp )
输入参数：U32 ID:									黑名单文件编号,编号为1-5
          U08 *pBlacklist:							要查找黑名单的首指针
          U08 *pBlacklistState:						要查找黑名单的状态的首指针
          U08 *pTemp:								用于合并黑名单区的数据,大小等于一个黑名单块的大小(pBlackBasicInfo->FlashSize * pBlackBasicInfo->FlashNumber)
输出参数：黑名单状态
返    回：NCAP_TRUE   		成功
		  0x0000FFFF        FLASH硬件故障
		  !NCAP_TRUE	    失败
***************************************************************************************************************/
U32 APP_FindBlacklist( U32 ID, U08 *pBlacklist, U08 *pBlacklistState, U08 *pTemp )
{
	_STRUCT_BLACKBASICINFO BlacklistInfo;			//定义黑名单基本信息
	U32 Rcode,id;									//定义函数返回值

	if( ( ID > DEF_NC_BlkFileNum ) || ( ID == 0 ) )
	{ return 200; }

	NC_FileLock();

	id = ( ID - 1 );

	//首先读函数基本信息,这是处理黑名单所必须的;
	Rcode = APP_ReadBlacklistFlashInfo( ID, &BlacklistInfo );
	if( Rcode != 0 )
	{ goto RET;	}

	//在判读黑名单指针是否过校验,如果不过校验则需要从FRAM中重新读取
	Rcode = AH_MemorDataCrc((U08 *)(&BlacklistFile[id]), BLACKLISTFILE_LENGTH - 2, 2 );
	if( Rcode != 0 )
	{
		Rcode = APP_OpenBlacklistFile( ID );
		if( Rcode != 0 )
	    { goto RET;	}
	}

	//如果文件没有创建,也是返回失败的
	if( BlacklistFile[id].OpenStat != 1 )
	{
		NC_FileUnLock();
		return 400;										//黑名单文件打开失败
	}
	
/*
如果由于某种原因导致上一次的黑名单排序没有正常进行,在此处在进行重新整理
这种情况理论上出现的几率非常小,但是为了防止出现这种情况,在此处做了处理
如果不处理,可能会导致查不到黑名单,主要是当增量黑名单在整个黑名单最后一
块的时候如果没有整理,会导致出现错误,此处是补救措施						
*/
	//如果增量黑名单的数量超过了每个黑名单块最大的数量,就需要进行排序(增量黑名单数量>=((Flash块大小*每个黑名单块的Flash块数)/黑名单长度))
	if( BlacklistFile[id].AddBlackNum >= ( ( BlacklistInfo.FlashSize * BlacklistInfo.FlashNumber ) / BlacklistInfo.BlackLength ) )
	{
		//需要进行排序,存入中间排序黑名单区
		Rcode = AH_SaveMiddleBlack( &BlacklistInfo , &BlacklistFile[id], pTemp ); //保存中间排序黑名单如果不成功则返回错误
		if( Rcode != 0 )
	    { goto RET;	}

		//更新FRAM存储器中的黑名单指针
		Rcode = AH_Write_BlkDirFile( ID, (U08 *)(&BlacklistFile[id]) );			  //保存中间排序黑名单如果不成功则返回错误
     	if( Rcode != 0 )
	    { goto RET;	}

		//如果中间排序块大于等于2块，需要将中间层合并到全量黑名单区
		if( BlacklistFile[id].MiddleBlockNum >= 2 )
		{
			Rcode = AH_SaveAllBlack( &BlacklistInfo , &BlacklistFile[id], pTemp );//保存全量黑名单如果不成功则返回错误
			if( Rcode != 0 )
	        { goto RET;	}

			//更新FRAM存储器中的黑名单指针
			Rcode = AH_Write_BlkDirFile( ID, (U08 *)(&BlacklistFile[id]) );
			if( Rcode != 0 )
	        { goto RET;	}
		}
	}

	//此处开始查找黑名单
	Rcode = AH_FindBlacklist( &BlacklistInfo, &BlacklistFile[id], pBlacklist, pBlacklistState, pTemp);

	RET:
	NC_FileUnLock();
	return Rcode;
}

